package main

import (
	"fmt"
	"os"
)

// a）在练习 5.4 的 for_loop.go 中，有一个常见的 for 循环打印数字。
// 在函数 tel() 中实现一个 for 循环，用协程开始这个函数并在其中给通道发送数字。
// main() 线程从通道中获取并打印。不要使用 time.Sleep() 来同步：goroutine_panic.go

// b）也许你的方案有效，但可能会引发运行时的 panic()：throw:all goroutines are asleep-deadlock!
// 为什么会这样？你如何解决这个问题？goroutine_close.go

// c）解决 a）的另外一种方式：使用一个额外的通道传递给协程，然后在结束的时候随便放点什么进去。
// main() 线程检查是否有数据发送给了这个通道，如果有就停止：goroutine_select.go

func tel(done chan<- bool) chan int {
	ch := make(chan int)
	go func() {
		for i := 0; i < 15; i++ {
			ch <- i
		}
		// b) 关闭chan以避免panic
		// close(ch)
		done <- true
	}()

	return ch
}

func main() {
	done := make(chan bool)
	ch := tel(done)

	for {
		// 使用select{} 阻塞直到done完成
		select {
		case v := <-ch:
			fmt.Println("The counter is at: ", v)
		case <-done:
			os.Exit(0)

		}
	}
}
